import tkinter as tk
from tkinter import messagebox
import datetime
from borax.calendars.lunardate import LunarDate  # 需先安装：pip install borax

class IDCardValidator:
    def __init__(self):
        # 省级行政区划字典（简化版）
        self.province_codes = {
            '11': '北京市', '12': '天津市', '13': '河北省', '14': '山西省', '15': '内蒙古自治区',
            '21': '辽宁省', '22': '吉林省', '23': '黑龙江省', '31': '上海市', '32': '江苏省',
            '33': '浙江省', '34': '安徽省', '35': '福建省', '36': '江西省', '37': '山东省',
            '41': '河南省', '42': '湖北省', '43': '湖南省', '44': '广东省', '45': '广西壮族自治区',
            '46': '海南省', '50': '重庆市', '51': '四川省', '52': '贵州省', '53': '云南省',
            '54': '西藏自治区', '61': '陕西省', '62': '甘肃省', '63': '青海省', '64': '宁夏回族自治区',
            '65': '新疆维吾尔自治区', '81': '香港', '82': '澳门'
        }
        
        # 创建主窗口
        self.window = tk.Tk()
        self.window.title("身份证信息查询系统")
        self.window.geometry("500x600")
        
        # 输入框
        tk.Label(self.window, text="请输入18位身份证号：").pack(pady=10)
        self.id_entry = tk.Entry(self.window, width=25)
        self.id_entry.pack()
        
        # 查询按钮
        tk.Button(self.window, text="查询信息", command=self.validate_and_show).pack(pady=10)
        
        # 结果显示区域
        self.result_text = tk.Text(self.window, height=20, width=60)
        self.result_text.pack(pady=10)
        
        self.window.mainloop()
    
    def validate_id(self, id_number):
        """验证身份证号合法性"""
        if len(id_number) != 18:
            return False, "身份证号长度应为18位"
        
        if not id_number[:17].isdigit():
            return False, "前17位必须为数字"
        
        last_char = id_number[-1]
        if not (last_char.isdigit() or last_char.upper() == 'X'):
            return False, "最后一位应为数字或X"
        
        # 校验码计算
        weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        check_codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']
        
        total = sum(int(id_number[i]) * weights[i] for i in range(17))
        calculated_code = check_codes[total % 11]
        
        if calculated_code.upper() != last_char.upper():
            return False, f"校验码错误，应为{calculated_code}"
        
        return True, "身份证号合法"
    
    def get_area_info(self, area_code):
        """获取籍贯信息"""
        province_code = area_code[:2]
        return self.province_codes.get(province_code, "未知地区")
    
    def get_birth_info(self, id_number):
        """获取生日信息"""
        birth_str = id_number[6:14]
        try:
            # 公历日期
            solar_date = datetime.datetime.strptime(birth_str, "%Y%m%d").date()
            weekday = solar_date.strftime("%A")  # 星期几
            
            # 农历日期
            lunar_date = LunarDate.from_solar_date(solar_date.year, solar_date.month, solar_date.day)
            lunar_str = lunar_date.cn_str()
            
            return solar_date, lunar_str, weekday
        except:
            return None, None, None
    
    def get_gender(self, id_number):
        """获取性别"""
        gender_code = int(id_number[:17])
        return "女" if gender_code % 2 == 0 else "男"

    def get_age(self, birth_date):
        """计算年龄"""
        today = datetime.date.today()
        age = today.year - birth_date.year
        if (today.month, today.day) < (birth_date.month, birth_date.day):
            age -= 1
        return age
    
    def validate_and_show(self):
        """验证并显示信息"""
        id_number = self.id_entry.get().strip()
        self.result_text.delete(1.0, tk.END)
        
        if not id_number:
            messagebox.showwarning("警告", "请输入身份证号！")
            return
        
        is_valid, msg = self.validate_id(id_number)
        
        if not is_valid:
            self.result_text.insert(tk.END, f"身份证号验证结果：{msg}\n")
            return
        
        # 显示基本信息
        self.result_text.insert(tk.END, f"身份证号验证结果：{msg}\n\n")
        
        # 获取并显示籍贯
        area_code = id_number[:6]
        area_info = self.get_area_info(area_code)
        self.result_text.insert(tk.END, f"籍贯信息：{area_info}（行政区划代码：{area_code}）\n")
        
        # 获取并显示生日信息
        solar_date, lunar_str, weekday = self.get_birth_info(id_number)
        if solar_date:
            self.result_text.insert(tk.END, "\n生日信息：\n")
            self.result_text.insert(tk.END, f"公历：{solar_date.strftime('%Y年%m月%d日')}（{weekday}）\n")
            self.result_text.insert(tk.END, f"农历：{lunar_str}\n")
            
            # 计算年龄
            age = self.get_age(solar_date)
            self.result_text.insert(tk.END, f"年龄：{age}岁\n")
        else:
            self.result_text.insert(tk.END, "\n生日信息解析失败\n")
        
        # 显示性别
        gender = self.get_gender(id_number)
        self.result_text.insert(tk.END, f"\n性别：{gender}\n")
        
        # 显示生肖（从农历日期获取）
        if solar_date:
            lunar_date = LunarDate.from_solar_date(solar_date.year, solar_date.month, solar_date.day)
            zodiac = lunar_date.animal
            self.result_text.insert(tk.END, f"生肖：{zodiac}\n")

# 运行程序
if __name__ == "__main__":
    IDCardValidator()
